/' Copyright (c) 2007 Scott Lembcke
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 '/
 
extern "C"

type cpContactBufferHeader_ as cpContactBufferHeader

type cpSpace
	'' *** User definable fields
	
	'' Number of iterations to use in the impulse solver to solve contacts.
	as integer			iterations
	
	'' Default gravity to supply when integrating rigid body motions.
	as cpVect			gravity
	
	'' Default damping to supply when integrating rigid body motions.
	as cpFloat			damping
	
	'' Speed threshold for a body to be considered idle.
	'' The default value of 0 means to let the space guess a good threshold based on gravity.
	as cpFloat			idleSpeedThreshold
	
	'' Time a group of bodies must remain idle in order to fall asleep
	'' The default value of INFINITY disables the sleeping algorithm.
	as cpFloat			sleepTimeThreshold
	
	'' Amount of encouraged penetration between colliding shapes..
	'' Used to reduce oscillating contacts and keep the collision cache warm.
	'' Defaults to 0.1. If you have poor simulation quality,
	'' increase this number as much as possible without allowing visible amounts of overlap.
	as cpFloat			collisionSlop
	
	'' Determines how fast overlapping shapes are pushed apart.
	'' Expressed as a fraction of the error remaining after each second.
	'' Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz.
	as cpFloat			collisionBias
	
	'' Number of frames that contact information should persist.
	'' Defaults to 3. There is probably never a reason to change this value.
	as cpTimestamp		collisionPersistence
	
	'' Rebuild the contact graph during each step. Must be enabled to use the cpBodyEachArbiter() function.
	'' Disabled by default for a small performance boost. Enabled implicitly when the sleeping feature is enabled.
	as cpBool			enableContactGraph
	
	'' User definable data pointer.
	'' Generally this points to your game's controller or game state
	'' class so you can access it when given a cpSpace reference in a callback.
	as cpDataPointer	data
	
	'' The designated static body for this space.
	'' You can modify this body, or replace it with your own static body.
	'' By default it points to a statically allocated cpBody in the cpSpace struct.
	as cpBody ptr		staticBody
	
	
	'' FreeBASIC note: all the following were enclosed in CP_PRIVATE, which I have disabled at compile time,
	'' and thought it would be pointless to use the CP_PRIVATE wrapper here.
	as cpTimestamp		stamp
	as cpFloat			curr_dt
	
	as cpArray_ ptr		bodies
	as cpArray_ ptr		rousedBodies
	as cpArray_ ptr		sleepingComponents
	
	as cpSpatialIndex ptr	staticShapes
	as cpSpatialIndex ptr	activeShapes
	
	as cpArray_ ptr		arbiters
	as cpContactBufferHeader_ ptr	contactBuffersHead
	as cpHashSet_ ptr		cachedArbiters
	as cpArray_ ptr		pooledArbiters
	as cpArray_ ptr		constraints
	
	as cpArray_ ptr		allocatedBuffers
	as integer			locked
	
	as cpHashSet_ ptr	collisionHandlers
	as cpCollisionHandler	defaultHandler
	as cpHashSet_ ptr	postStepCallbacks
	
	as cpBody			_staticBody
end type

' Basic allocation/destruction functions.
declare function cpSpaceAlloc cdecl alias "cpSpaceAlloc" ( ) as cpSpace ptr
declare function cpSpaceInit cdecl alias "cpSpaceInit" ( byval spacep as cpSpace ptr ) as cpSpace ptr
declare function cpSpaceNew cdecl alias "cpSpaceNew" ( ) as cpSpace ptr

declare sub cpSpaceDestroy cdecl alias "cpSpaceDestroy" ( byval spacep as cpSpace ptr )
declare sub cpSpaceFree cdecl alias "cpSpaceFree" ( byval spacep as cpSpace ptr )

#define CP_DefineSpaceStructGetter(type, member, name) function cpSpaceGet##name cdecl( byval s as const cpSpace ptr ) as type : return s->member : end function

#define CP_DefineSpaceStructSetter(type, member, name) sub cpSpaceSet##name cdecl( byval s as cpSpace ptr, byval value as type ) : s->member = value : end sub

#macro CP_DefineSpaceStructProperty(type, member, name)
CP_DefineSpaceStructGetter(type, member, name)
CP_DefineSpaceStructSetter(type, member, name)
#endmacro

CP_DefineSpaceStructProperty(integer, iterations, Iterations)
CP_DefineSpaceStructProperty(cpVect, gravity, Gravity)
CP_DefineSpaceStructProperty(cpFloat, damping, Damping)
CP_DefineSpaceStructProperty(cpFloat, idleSpeedThreshold, IdleSpeedThreshold)
CP_DefineSpaceStructProperty(cpFloat, sleepTimeThreshold, SleepTimeThreshold)
CP_DefineSpaceStructProperty(cpFloat, collisionSlop, CollisionSlop)
CP_DefineSpaceStructProperty(cpFloat, collisionBias, CollisionBias)
CP_DefineSpaceStructProperty(cpTimestamp, collisionPersistence, CollisionPersistence)
CP_DefineSpaceStructProperty(cpBool, enableContactGraph, EnableContactGraph)
CP_DefineSpaceStructProperty(cpDataPointer, data, UserData)
CP_DefineSpaceStructGetter(cpBody ptr, staticBody, StaticBody)
CP_DefineSpaceStructGetter(cpFloat, curr_dt, CurrentTimeStep)

'' Set a default collision handler for this space.
'' The default collision handler is invoked for each colliding pair of shapes
'' that isn't explicitly handled by a specific collision handler.
'' You can pass NULL for any function you don't want to implement.
declare sub cpSpaceSetDefaultCollisionHandler cdecl alias "cpSpaceSetDefaultCollisionHandler" ( _
	byval as cpSpace ptr, _
	byval as cpCollisionBeginFunc, _
	byval as cpCollisionPreSolveFunc, _
	byval as cpCollisionPostSolveFunc, _
	byval as cpCollisionSeparateFunc, _
	byval as any ptr _
)

'' Set a collision handler to be used whenever the two shapes with the given collision types collide.
'' You can pass NULL for any function you don't want to implement.
declare sub cpSpaceAddCollisionHandler cdecl alias "cpSpaceAddCollisionHandler" ( _
	byval as cpSpace ptr, _
	byval as cpCollisionType, _
	byval as cpCollisionType, _
	byval as cpCollisionBeginFunc, _
	byval as cpCollisionPreSolveFunc, _
	byval as cpCollisionPostSolveFunc, _
	byval as cpCollisionSeparateFunc, _
	byval as any ptr _
)

'' Unset a collision handler.
declare sub cpSpaceRemoveCollisionHandler cdecl alias "cpSpaceRemoveCollisionHandler" ( _
	byval as cpSpace ptr, _
	byval as cpCollisionType, _
	byval as cpCollisionType _
)

' Add and remove entities from the system.
declare function cpSpaceAddShape cdecl alias "cpSpaceAddShape" ( byval as cpSpace ptr, byval as cpShape ptr ) as cpShape ptr
declare function cpSpaceAddStaticShape cdecl alias "cpSpaceAddStaticShape" ( byval as cpSpace ptr, byval as cpShape ptr ) as cpShape ptr
declare function cpSpaceAddBody cdecl alias "cpSpaceAddBody" ( byval as cpSpace ptr, byval as cpBody ptr ) as cpBody ptr
declare function cpSpaceAddConstraint cdecl alias "cpSpaceAddConstraint" ( byval as cpSpace ptr, byval as cpConstraint ptr ) as cpConstraint ptr

declare sub cpSpaceRemoveShape cdecl alias "cpSpaceRemoveShape" ( byval as cpSpace ptr, byval as cpShape ptr )
declare sub cpSpaceRemoveStaticShape cdecl alias "cpSpaceRemoveStaticShape" ( byval as cpSpace ptr, byval as cpShape ptr )
declare sub cpSpaceRemoveBody cdecl alias "cpSpaceRemoveBody" ( byval as cpSpace ptr, byval as cpBody ptr )
declare sub cpSpaceRemoveConstraint cdecl alias "cpSpaceRemoveConstraint" ( byval as cpSpace ptr, byval as cpConstraint ptr )

'' Test if a collision shape has been added to the space.
declare function cpSpaceContainsShape cdecl alias "cpSpaceContainsShape" ( byval as cpSpace ptr, byval as cpShape ptr ) as cpBool
'' Test if a rigid body has been added to the space.
declare function cpSpaceContainsBody cdecl alias "cpSpaceContainsBody" ( byval as cpSpace ptr, byval as cpBody ptr ) as cpBool
'' Test if a constraint has been added to the space.
declare function cpSpaceContainsConstraint cdecl alias "cpSpaceContainsConstraint" ( byval as cpSpace ptr, byval as cpConstraint ptr ) as cpBool


'' Post Step function definition
type cpPostStepFunc as sub cdecl( byval as cpSpace ptr, byval as any ptr, byval as any ptr )
'' Register a post step function to be called after cpSpaceStep() has finished.
'' obj is used a key, you can only register one callback per unique value for obj
declare sub cpSpaceAddPostStepCallback( byval as cpSpace ptr, byval as cpPostStepFunc, byval as any ptr, byval as any ptr )

'' Point query callback function
type cpSpacePointQueryFunc as sub cdecl( byval as cpShape ptr, byval as any ptr )
declare sub cpSpacePointQuery cdecl alias "cpSpacePointQuery" ( byval as cpSpace ptr, byval as cpVect, byval as cpLayers, byval as cpGroup, byval as cpSpacePointQueryFunc, byval as any ptr )
declare function cpSpacePointQueryFirst cdecl alias "cpSpacePointQueryFirst" ( byval as cpSpace ptr, byval as cpVect, byval as cpLayers, byval as cpGroup ) as cpShape ptr

'' Segment query callback function
type cpSpaceSegmentQueryFunc as sub cdecl( byval as cpShape ptr, byval as cpFloat, byval as cpVect, byval as any ptr )
declare function cpSpaceSegmentQuery cdecl alias "cpSpaceSegmentQuery" ( byval as cpSpace ptr, byval as cpVect, byval as cpVect, byval as cpLayers, byval as cpGroup, byval as cpSpaceSegmentQueryFunc, byval as any ptr ) as cpBool
declare function cpSpaceSegmentQueryFirst cdecl alias "cpSpaceSegmentQueryFirst" ( byval as cpSpace ptr, byval as cpVect, byval as cpVect, byval as cpLayers, byval as cpGroup, byval as cpSegmentQueryInfo ptr ) as cpShape ptr

'' BB query callback function
type cpSpaceBBQueryFunc as sub cdecl( byval as cpSpace ptr, byval as any ptr )
declare sub cpSpaceBBQuery cdecl alias "cpSpaceBBQuery" ( byval as cpSpace ptr, byval as cpBB, byval as cpLayers, byval as cpGroup, byval as cpSpaceBBQueryFunc, byval as any ptr )

'' Call cpBodyActivate() for any shape that is overlaps the given shape.
declare sub cpSpaceActivateShapesTouchingShape cdecl alias "cpSpaceActivateShapesTouchingShape" ( byval as cpSpace ptr, byval as cpShape ptr )

'' Iterator function for iterating the bodies in a space.
type cpSpaceBodyIterator as sub cdecl( byval as cpBody ptr, byval as any ptr )
declare sub cpSpaceEachBody cdecl alias "cpSpaceEachBody" ( byval as cpSpace ptr, byval as cpSpaceBodyIterator, byval as any ptr )

'' Space/body iterator callback function type.
type cpSpaceShapeIteratorFunc as sub cdecl( byval as cpShape ptr, byval as any ptr )
'' Call @c func for each shape in the space.
declare sub cpSpaceEachShape cdecl alias "cpSpaceEachShape" ( byval as cpSpace ptr, byval as cpSpaceShapeIteratorFunc, byval as any ptr )

'' Space/constraint iterator callback function type.
type cpSpaceConstraintIteratorFunc as sub cdecl( byval as cpConstraint ptr, byval as any ptr )
'' Call @c func for each shape in the space.
declare sub cpSpaceEachConstraint cdecl alias "cpSpaceEachConstraint" ( byval as cpSpace ptr, byval as cpSpaceConstraintIteratorFunc, byval as any ptr )

'' Update the collision detection info for the static shapes in the space.
declare sub cpSpaceReindexStatic cdecl alias "cpSpaceReindexStatic" ( byval as cpSpace ptr )
'' Update the collision detection data for a specific shape in the space.
declare sub cpSpaceReindexShape cdecl alias "cpSpaceReindexShape" ( byval as cpSpace ptr, byval as cpShape ptr )
'' Update the collision detection data for all shapes attached to a body.
declare sub cpSpaceReindexShapesForBody cdecl alias "cpSpaceReindexShapesForBody" ( byval as cpSpace ptr, byval as cpBody ptr )

'' Switch the space to use a spatial has as it's spatial index.
declare sub cpSpaceUseSpatialHash cdecl alias "cpSpaceUseSpatialHash" ( byval as cpSpace ptr, byval as cpFloat, byval as integer )

'' Step the space forward in time by @c dt.
declare sub cpSpaceStep cdecl alias "cpSpaceStep" ( byval as cpSpace ptr, byval as cpFloat )

end extern
